package dongze.com.ckdj.activity;

import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.ServiceConnection;
import android.databinding.DataBindingUtil;
import android.databinding.Observable;
import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.provider.MediaStore;
import android.support.v4.content.FileProvider;
import android.support.v7.app.AlertDialog;
import android.support.v7.widget.GridLayoutManager;
import android.support.v7.widget.RecyclerView;
import android.text.TextUtils;
import android.util.Log;
import android.util.Pair;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup;
import android.widget.AdapterView;
import android.widget.FrameLayout;
import android.widget.GridLayout;
import android.widget.Toast;

import com.google.gson.JsonObject;

import org.greenrobot.greendao.query.QueryBuilder;

import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.inject.Inject;

import butterknife.BindView;
import butterknife.ButterKnife;
import dongze.com.ckdj.BR;
import dongze.com.ckdj.R;
import dongze.com.ckdj.adapter.ImageListAdapter;
import dongze.com.ckdj.dagger.component.UserComponent;
import dongze.com.ckdj.data.entity.response.BrandResponse;
import dongze.com.ckdj.data.entity.response.User;
import dongze.com.ckdj.databinding.InformationItemSpinnerBinding;
import dongze.com.ckdj.databinding.InformationItemTextBinding;
import dongze.com.ckdj.databinding.VehicleNumberItemBinding;
import dongze.com.ckdj.databinding.model.InformationItemSpinnerModel;
import dongze.com.ckdj.databinding.model.InformationItemTextModel;
import dongze.com.ckdj.databinding.model.MassLossImageItemModel;
import dongze.com.ckdj.databinding.model.VehicleNumberModel;
import dongze.com.ckdj.map.MapUtil;
import dongze.com.ckdj.persistence.DaoHelper;
import dongze.com.ckdj.persistence.dao.DaoSession;
import dongze.com.ckdj.persistence.dao.Image;
import dongze.com.ckdj.persistence.dao.ImageDao;
import dongze.com.ckdj.persistence.dao.ServerUploadTask;
import dongze.com.ckdj.persistence.dao.ServerUploadTaskDao;
import dongze.com.ckdj.service.IImageUploadCallback;
import dongze.com.ckdj.service.IImageUploadService;
import dongze.com.ckdj.service.ImageUploadService;
import dongze.com.ckdj.service.ImageUploadTask;
import dongze.com.ckdj.ui.ImageUploadDialog;
import dongze.com.ckdj.ui.StateDialog;
import dongze.com.ckdj.util.MyLog;
import dongze.com.ckdj.util.Util;
import io.reactivex.observers.DisposableObserver;


/**
 * Created by fanqwz on 2017/9/12.
 */

public class RandomInspectionActivty extends ProgressableActivity {
    private static final String TAG = RandomInspectionActivty.class.getSimpleName();
    private static final int IMAGE_COUNT = 12;
    private static final String IMAGE_PRIFIX = "randomInspection";
    private static final int PHOTO_INTENT = 1025;
    private static final int BACK_PRESSED_MSG = 1028;

    @BindView(R.id.basic_info_container)
    GridLayout mBasicInfoLayout;
    @BindView(R.id.vehicle_number_container)
    ViewGroup mVehicleNumberContainer;
    @BindView(R.id.image_container)
    RecyclerView mGlImage;

    MapUtil mapUtil;
    @Inject
    User mUser;
    @Inject
    DaoSession daoSession;

    InformationItemTextModel mTimeModel = new InformationItemTextModel();
    InformationItemTextModel mUserModel = new InformationItemTextModel();
    VehicleNumberModel mVehicleNumberModel = new VehicleNumberModel();
    InformationItemSpinnerModel mBrandModel = new InformationItemSpinnerModel();
    MassLossImageItemModel[] imageModels = new MassLossImageItemModel[IMAGE_COUNT];
    File[] capturedImage = new File[IMAGE_COUNT];
    private DisposableObserver mPendingDisposable;

    IImageUploadService mService;
    android.os.Handler mHandler;
    String mCurrentVehicleNumber;
    List<BrandResponse> brands;

    ServiceConnection mConn = new ServiceConnection() {
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            MyLog.d(TAG, "onServiceConnected: ");
            mService = IImageUploadService.Stub.asInterface(service);
//            try {
//                mService.addCallback(mBinder);
//            } catch (RemoteException e) {
//                e.printStackTrace();
//            }
        }

        @Override
        public void onServiceDisconnected(ComponentName name) {
            MyLog.d(TAG, "onServiceDisconnected: ");
//            try {
//                mService.removeCallback(mBinder);
//            } catch (RemoteException e) {
//                e.printStackTrace();
//            }
            mService = null;
        }
    };

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_random_inspection);
        ButterKnife.bind(this);
        mHandler = new Handler(getMainLooper());
        mapUtil = new MapUtil(getAppCompenent());

        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(Intent.ACTION_TIME_TICK);
        registerReceiver(mTimeReceiver, intentFilter);

        bindService(new Intent(this, ImageUploadService.class), mConn, BIND_AUTO_CREATE);

        if (getComponent(UserComponent.class) != null) {
            getComponent(UserComponent.class).inject(this);
        } else {
            finish();
            return;
        }

        mTimeModel.setKey("当前时间");
        mTimeModel.setValue(Util.getCurrentTime(this));
        addBasicInfoItem(mTimeModel);

        mUserModel.setKey("登陆人员");
        mUserModel.setValue(mUser.getRemark() + "-" + mUser.getUser_name());
        addBasicInfoItem(mUserModel);

        addVehicleNumber(mVehicleNumberModel);

        mBrandModel.setKey("品牌");
        addBrandName(mBrandModel);

        buildRandomInspectionImage();

        loadBrands();
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        getMenuInflater().inflate(R.menu.random_inspection, menu);
        return super.onCreateOptionsMenu(menu);
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        if (item.getItemId() == R.id.save) {
            doUpload();
            return true;
        } else {
            return super.onOptionsItemSelected(item);
        }
    }

    @Override
    protected void onDestroy() {
        unbindService(mConn);
        unregisterReceiver(mTimeReceiver);
        mapUtil.dispose();
        super.onDestroy();
    }

    @Override
    public void onBackPressed() {
        if (mHandler.hasMessages(BACK_PRESSED_MSG)) {
            super.onBackPressed();
        } else {
            Toast.makeText(this, "再次按下返回键退出当前页面", Toast.LENGTH_SHORT).show();
            mHandler.sendMessageDelayed(mHandler.obtainMessage(BACK_PRESSED_MSG), 1500);
        }
    }

    private void addBasicInfoItem(InformationItemTextModel model) {
        InformationItemTextBinding binding = DataBindingUtil.inflate(LayoutInflater.from(this), R.layout.information_item_text, mBasicInfoLayout, false);
        binding.getRoot().setTag(binding);
        binding.setVehicleInformationItemText(model);
        int count = mBasicInfoLayout.getColumnCount();
        GridLayout.LayoutParams params = new GridLayout.LayoutParams(GridLayout.spec(mBasicInfoLayout.getChildCount() / count, 1), GridLayout.spec(mBasicInfoLayout.getChildCount() % count, 1));
        params.width = (getResources().getDisplayMetrics().widthPixels) / count;

//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//            params = new GridLayout.LayoutParams(GridLayout.spec(mBasicInfoLayout.getChildCount() / count, 1, 0.5f), GridLayout.spec(mBasicInfoLayout.getChildCount() % count, 1, 0.5f));
//        }

        int margin = getResources().getDimensionPixelSize(R.dimen.basic_info_item_margin);
        params.setMargins(margin, margin, margin, margin);
        mBasicInfoLayout.addView(binding.getRoot(), params);
    }

    private void addBrandName(InformationItemSpinnerModel model) {
        InformationItemSpinnerBinding binding = DataBindingUtil.inflate(LayoutInflater.from(this), R.layout.information_item_spinner, mBasicInfoLayout, false);
        binding.getRoot().setTag(binding);
        binding.setVehicleInformationItemSpinner(model);
//        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(getResources().getDimensionPixelSize(R.dimen.name_plate_brand_width), ViewGroup.LayoutParams.WRAP_CONTENT);
//        int margin = getResources().getDimensionPixelSize(R.dimen.basic_info_item_margin);
//        params.setMargins(margin, margin, margin, margin);
//        params.gravity = Gravity.LEFT | Gravity.CENTER_VERTICAL;
        int count = mBasicInfoLayout.getColumnCount();
        GridLayout.LayoutParams params = new GridLayout.LayoutParams(GridLayout.spec(mBasicInfoLayout.getChildCount() / count, 1), GridLayout.spec(mBasicInfoLayout.getChildCount() % count, 1));
        params.width = (getResources().getDisplayMetrics().widthPixels) / count;

//        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
//            params = new GridLayout.LayoutParams(GridLayout.spec(mBasicInfoLayout.getChildCount() / count, 1, 0.5f), GridLayout.spec(mBasicInfoLayout.getChildCount() % count, 1, 0.5f));
//        }

        int margin = getResources().getDimensionPixelSize(R.dimen.basic_info_item_margin);
        params.setMargins(margin, margin, margin, margin);
        mBasicInfoLayout.addView(binding.getRoot(), params);
    }

    private void addVehicleNumber(VehicleNumberModel model) {
        VehicleNumberItemBinding vehicleNumberItemBinding = DataBindingUtil.inflate(LayoutInflater.from(this), R.layout.vehicle_number_item, mVehicleNumberContainer, false);
        model.setKey("车架号");
        model.setOnItemClickListener(mOnVehicleNumberClick);
        vehicleNumberItemBinding.setInformationItemAutoCompleteTextModel(model);
        model.addOnPropertyChangedCallback(mOnVehicleNumberChangedListener);
        FrameLayout.LayoutParams params = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
        int margin = getResources().getDimensionPixelSize(R.dimen.basic_info_item_margin);
        params.setMargins(margin, margin, margin, margin);
        params.gravity = Gravity.CENTER;
        mVehicleNumberContainer.addView(vehicleNumberItemBinding.getRoot(), params);
    }

    // 照片网格
    private void buildRandomInspectionImage() {
        for (int i = 0; i < IMAGE_COUNT; i++) {
            final int value = i;
            final MassLossImageItemModel image = new MassLossImageItemModel();
            image.setOnNewClicked(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    if (!Util.checkCapturePermission(RandomInspectionActivty.this))
                        return;

                    File file = Util.getImageFile(IMAGE_PRIFIX);

                    Intent intent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);

                    int currentapiVersion = android.os.Build.VERSION.SDK_INT;
                    if (currentapiVersion < 24) {
                        intent.putExtra(MediaStore.EXTRA_OUTPUT, Uri.fromFile(file));
                        startActivityForResult(intent, PHOTO_INTENT + value);
                    } else {
                        Uri uri = FileProvider.getUriForFile(RandomInspectionActivty.this, "dongze.com.ckdj.fileprovider", file);
                        intent.putExtra(MediaStore.EXTRA_OUTPUT, uri);
                        intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION);
                        startActivityForResult(intent, PHOTO_INTENT + value);
                    }
                    capturedImage[value] = file;
                }
            });
            image.setOnDeleteClicked(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    image.setImageFile(null);
                    Util.deleteFile(capturedImage[value].getAbsolutePath());
                    capturedImage[value] = null;
                }
            });
            image.setOnImageClicked(new View.OnClickListener() {
                @Override
                public void onClick(View v) {
                    Util.ViewImage(RandomInspectionActivty.this, capturedImage[value]);
                }
            });
            imageModels[i] = image;

            mGlImage.setAdapter(new ImageListAdapter(imageModels));
            mGlImage.setLayoutManager(new GridLayoutManager(this, 3));
        }
    }

    private void loadBrands() {
        mapUtil.getBrands("1",
                new DisposableObserver<List<BrandResponse>>() {
                    @Override
                    protected void onStart() {
                        super.onStart();
                        doProcessing();
                    }

                    @Override
                    public void onNext(List<BrandResponse> value) {
                        String pref = Util.getPreference(RandomInspectionActivty.this, Util.PREF_SELECTED_BRAND, null);
                        String[] entries = new String[value.size()];

                        for (int i = 0; i < value.size(); i++) {
                            entries[i] = value.get(i).getBrand_name();
                        }

                        mBrandModel.setValues(entries);
                        mBrandModel.setPosition(0);
                        brands = value;

                        for (int i = 0; i < value.size(); i++) {
                            if (TextUtils.equals(value.get(i).getBrand_code(), pref))
                                mBrandModel.setPosition(i);
                        }
                    }

                    @Override
                    public void onError(Throwable e) {
                        MyLog.e(TAG, "onError: ", e);
                        new AlertDialog.Builder(RandomInspectionActivty.this)
                                .setMessage(e.getMessage())
                                .create()
                                .show();
                        finishProcessing();
                    }

                    @Override
                    public void onComplete() {
                        finishProcessing();
                    }
                });
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if (requestCode >= PHOTO_INTENT && requestCode <= PHOTO_INTENT + IMAGE_COUNT && resultCode == RESULT_OK) {
            int offset = requestCode - PHOTO_INTENT;

            if (!capturedImage[offset].exists())
                return;

//            try {
//                BitmapFactory.Options o = new BitmapFactory.Options();
//                o.inSampleSize = 4;
//                Bitmap b = BitmapFactory.decodeFile(capturedImage[offset].getAbsolutePath(), o);
//                imageModels[offset].setImage(new BitmapDrawable(getResources(), b));
//            } catch (Exception e) {
//                e.printStackTrace();
//            }
            imageModels[offset].setImageFile(capturedImage[offset].getAbsolutePath());
        } else {
            super.onActivityResult(requestCode, resultCode, data);
        }
    }

    private void doUpload() {
        if (mCurrentVehicleNumber == null)
            return;

        try {
            if (Util.DISABLE.equals(Util.getPreference(getApplicationContext(), Util.PREF_UPLOAD_BACKGROUND, Util.DISABLE))) {
                doUploadImage();
            } else {
                saveUploadImageRecordToService();
            }
        } catch (Exception e) {
            e.printStackTrace();
            new AlertDialog.Builder(RandomInspectionActivty.this)
                    .setMessage("上传图片失败！！！！" + e.getMessage())
                    .create()
                    .show();
        }

    }

    //使用service，离线上传
    private void saveUploadImageRecordToService() {
        final List<File> images = new ArrayList<>(capturedImage.length);

        for (int i = 0; i < capturedImage.length; i++) {
            if (capturedImage[i] != null)
                images.add(capturedImage[i]);
        }

        if (images.size() == 0)
            return;

        if (mService != null) {
            try {
                for (int i = 0; i < images.size(); i++) {
                    mService.addTask(DaoHelper.createRandomInspectionTask(daoSession,
                            mCurrentVehicleNumber,
                            mUser.getUser_no(),
                            i == 0 ? "img" : "img" + String.format("%02d", i + 1/*从1开始*/),
                            images.get(i).getAbsolutePath(),
                            new Date()));
                }
            } catch (RemoteException e) {
                e.printStackTrace();
            }
        } else {
            new AlertDialog.Builder(this)
                    .setTitle("错误")
                    .setMessage("图片上传服务不可用,请重启app并重新录入数据！")
                    .create()
                    .show();
        }
    }


    //同步上传
    private void doUploadImage() {
        final String vin = mCurrentVehicleNumber;
        final String userNo = mUser.getUser_no();
        final JsonObject jsonObject = new JsonObject();
        jsonObject.addProperty("vin", vin);
        jsonObject.addProperty("userNo", userNo);
        boolean isEmpty = true;
        for (int i = 0; i < capturedImage.length; i++) {
            if (capturedImage[i] != null)
                isEmpty = false;
        }

        if (isEmpty) {
            return;
        }

        final List<ImageUploadTask> tasks = new ArrayList<>();
        final Map<Long, String> index = new HashMap<>();
        final List<File> images = new ArrayList<>();

        for (int i = 0; i < capturedImage.length; i++) {
            if (capturedImage[i] == null)
                continue;

            ImageUploadTask task = DaoHelper.createImageTask(daoSession,
                    capturedImage[i].getAbsolutePath());
            tasks.add(task);
            index.put(task.getId(), "img" + String.format("%02d", i + 1/*从1开始*/));
            images.add(capturedImage[i]);
        }

        final ImageUploadDialog imageUploadDialog = new ImageUploadDialog(RandomInspectionActivty.this, tasks, images, new ImageUploadDialog.CallBack() {
            @Override
            public void onTaskFinished(ImageUploadTask task) {
                if (index.get(task.getId()) == null)
                    return;

                daoSession.clear();
                QueryBuilder<Image> qb = daoSession.getImageDao().queryBuilder();
                qb.join(ImageDao.Properties.Id, ServerUploadTask.class, ServerUploadTaskDao.Properties.ImageId)
                        .where(ServerUploadTaskDao.Properties.Id.eq(task.getId()));
                Image image = qb.unique();
                if (image != null) {
                    jsonObject.addProperty(index.get(task.getId()), image.getServerPath());
                } else {
                    Toast.makeText(RandomInspectionActivty.this, "找不到任务" + task.getId() + "对应的image", Toast.LENGTH_SHORT).show();
                }

                try {
                    mService.deleteTask(task.getId());
                } catch (RemoteException e) {
                    e.printStackTrace();
                }
            }

            @Override
            public void onAllTaskFinished() {

                mapUtil.upLoadRandomInspection(jsonObject, new DisposableObserver<String>() {
                    @Override
                    public void onNext(String value) {

                    }

                    @Override
                    public void onError(Throwable e) {
                        e.printStackTrace();

                        new AlertDialog.Builder(RandomInspectionActivty.this)
                                .setMessage(e.getMessage())
                                .create()
                                .show();
                    }

                    @Override
                    public void onComplete() {
                        Toast.makeText(RandomInspectionActivty.this, "上传成功", Toast.LENGTH_SHORT).show();
                    }
                });
            }
        });
        imageUploadDialog.show();
        imageUploadDialog.setOnDismissListener(new DialogInterface.OnDismissListener() {
            @Override
            public void onDismiss(DialogInterface dialog) {
                for (MassLossImageItemModel model :
                        imageModels) {
                    model.setImageFile(null);
                }

                for (int i = 0; i < capturedImage.length; i++) {
                    capturedImage[i] = null;
                }
            }
        });
    }

    private Observable.OnPropertyChangedCallback mOnVehicleNumberChangedListener = new Observable.OnPropertyChangedCallback() {
        @Override
        public void onPropertyChanged(Observable sender, int propertyId) {
            if (propertyId == BR.value) {
                mHandler.removeCallbacks(mGetAutoCompleteDateRunnable);
                mHandler.postDelayed(mGetAutoCompleteDateRunnable, 300);
            }
        }
    };

    private Runnable mGetAutoCompleteDateRunnable = new Runnable() {
        @Override
        public void run() {
            MyLog.d(TAG, "run:mGetAutoCompleteDateRunnable");

            if (mVehicleNumberModel.getValue() == null
                    || mVehicleNumberModel.getValue().length() <= 3
                    || mVehicleNumberModel.getValue().equals(mCurrentVehicleNumber)
                    || mBrandModel.getValues() == null
                    || brands == null)
                return;

            if (mPendingDisposable != null && !mPendingDisposable.isDisposed()) {
                mPendingDisposable.dispose();
            }

            mPendingDisposable = new DisposableObserver<List<Pair<String, String>>>() {
                @Override
                protected void onStart() {
                    super.onStart();
//                    showProgressBar();
                    mVehicleNumberModel.setEntries(Arrays.asList(new Pair<String, String>("<查询中......>", null)));
                }

                @Override
                public void onNext(List<Pair<String, String>> value) {
                    MyLog.d(TAG, "onNext: mGetAutoCompleteDateRunnable");
                    mVehicleNumberModel.setEntries(value);
                    if (value.size() == 1) {
                        // 只有一个结果自动填充并开始做下一步查询
                        mVehicleNumberModel.setEntries(null);
                        mCurrentVehicleNumber = value.get(0).first;
                        mVehicleNumberModel.setValue(null);
                        mVehicleNumberModel.setHint(mCurrentVehicleNumber);
                    } else if (value.size() == 0) {
                        mVehicleNumberModel.setEntries(Arrays.asList(new Pair<String, String>("<找不到车架号>", null)));
                    }
                }

                @Override
                public void onError(Throwable e) {
                    e.printStackTrace();
                    mVehicleNumberModel.setEntries(Arrays.asList(new Pair<String, String>("<查询出错>", null)));
//                    hideProgressBar();
                }

                @Override
                public void onComplete() {
//                    hideProgressBar();
                }
            };

            mapUtil.mapInformationItemAutoCompleteTextModel(
                    mVehicleNumberModel.getValue(),
                    brands.get(mBrandModel.getPosition()).getBrand_code(), ""
                    , mPendingDisposable);
        }
    };


    AdapterView.OnItemClickListener mOnVehicleNumberClick = new AdapterView.OnItemClickListener() {
        @Override
        public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
            // start get detail info
            MyLog.d(TAG, "onItemClick: ");
            mHandler.removeCallbacks(mGetAutoCompleteDateRunnable);

            //check
            try {
                if (mVehicleNumberModel.getValue() == null
                        || !mVehicleNumberModel.getValue().equals(
                        mVehicleNumberModel.getEntries().get(position).first)
                        || (mVehicleNumberModel.getValue().startsWith("<") && mVehicleNumberModel.getValue().endsWith(">"))) {
                    MyLog.e(TAG, "onItemClick: check data consistency failed");
                    return;
                }
            } catch (Exception e) {
                e.printStackTrace();
                return;
            }

            mCurrentVehicleNumber = mVehicleNumberModel.getValue();
            mVehicleNumberModel.setValue(null);
            mVehicleNumberModel.setHint(mCurrentVehicleNumber);
        }
    };


    BroadcastReceiver mTimeReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            if (intent.getAction().equals(Intent.ACTION_TIME_TICK)) {
                mTimeModel.setValue(Util.getCurrentTime(RandomInspectionActivty.this));
            }
        }
    };
}
